<?php
/*******************************************************************************

    FinalsClub.org is a platform for students and faculty to collaborate
    and share their knowledge with the world.

    Copyright (C) 2009  Andrew Magliozzi

    This file is a part of FinalsClub.org.

    FinalsClub.org is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    To contact FinalsClub.org, send an email to info@finalsclub.org, or
    send mail to Finals Club, c/o Veritas Tutors, 1132 Massachusetts Avenue,
    Cambridge, MA 02138.

*******************************************************************************/

/**
 * groups actions.
 *
 * @package    FinalsClub
 * @subpackage groups
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 12479 2008-10-31 10:54:40Z fabien $
 */
class groupsActions extends sfActions {

	/**
	 * Displays all the groups available
	 * @param $request
	 * @return sfView::SUCCESS
	 */
	public function executeIndex(sfWebRequest $request) {
		if($this->getUser()->isAuthenticated()) {
			$networkid = $request->getParameter('network_id');
			if(!$networkid) {
				$user = UserPeer::retrieveByPK($this->getUser()->getId());
				$networkid = $user->getNetworkId();
				$this->networkname = $user->getNetworkName();
			}
			$this->groups = GroupPeer::retrieveAll($this->getUser()->getId(), $networkid, $this->getUser()->isAdmin());	
			$this->networkid = $networkid;
		} else {
			$this->setTemplate('public');
		}
		$this->networks = UserPeer::$networks;
	}
	
	/**
	 * Presents a form for creating or editing a group
	 * @param $request
	 * @return sfView::SUCCESS
	 */
	public function executeEdit(sfWebRequest $request) {
		$group = GroupPeer::retrieveById($request->getParameter('id'));
		// only display the form if the user is either creating a new group or an admin of the group
		if($group && $this->getUser()->isGroupAdmin($group->getId()) === false) {
			$this->getUser()->setFlash('notice', 'You do not have permissions to edit this group.');
			$this->redirect('groups/show', 300);	// access denied
		}
		
		// if updating an existing group, pass the group id to the form
		$this->form = new GroupForm($group, array('network_id' => $this->getUser()->getNetworkId()));
		$this->form->setDefault('course_ids', 
			GroupCoursePeer::getSelectedCourseIds(isset($group) ? $group->getId() : null));
		
		// retrieve all group members associated with the current group
		if($group && $groupMembers = GroupMemberPeer::retrieveByGroupId($group->getId())) {
			$this->member_forms = $this->buildMemberForms($groupMembers);
		}
	}
	
	/**
	 * Displays information for an individual group
	 * @param $request, requires the group id within the request
	 * @return sfView::SUCCESS
	 */
	public function executeShow(sfWebRequest $request) {
		$this->forward404Unless($request->getParameter('id'));
		// check if the user is a member of the group
		$groupMember = GroupMemberPeer::retrieveByUserIdAndGroupId($this->getUser()->getId(), $request->getParameter('id'));
		$this->group = GroupPeer::retrieveById($request->getParameter('id'));
		
		if($this->getUser()->isAdmin()) {
			
		} else if(!$groupMember) {
			$this->setTemplate('nonmember');
		} else if($groupMember->getStatus() != GroupMemberPeer::APPROVED_STATUS) {
			$this->setTemplate('pending');
		}
		
	
	}
	
	/**
	 * Creates a new group or Updates an existing group. Also handles setting the default permissions on a newly created group
	 * or updating existing permission for an existing group. Only group admins have permission to modify and update any
	 * properties of a group.
	 * @param $request
	 * @return sfView::SUCCESS
	 */
	public function executeUpdate(sfWebRequest $request) {
		$this->forward404Unless($request->isMethod('post'));
		
		$groupRequest = $request->getParameter('group');
		$groupRequest['network_id'] = $this->getUser()->getNetworkId();
		$groupRequest['user_id'] = $this->getUser()->getId();

		$group = null;
		$setDefaultAdmin = true;
		if($groupRequest['id'] != null) {
			$group = GroupPeer::retrieveById($groupRequest['id']);
			if($group && $this->getUser()->isGroupAdmin($group->getId()) === false) {
				$this->getUser()->setFlash('notice', 'You do not have permissions to edit this group.');
				$this->redirect('groups/show', 300);	// access denied
			}			
			$setDefaultAdmin = false;
		} else {
			// force null if the id is not specified in the request so propel knows it's a new object
			$groupRequest['id'] = null;
		}
		
		$this->form = new GroupForm($group, array('network_id' => $this->getUser()->getNetworkId()));
		$this->form->bind($groupRequest);
		
		if($this->form->isValid()) {
			// if this is a new group, then prepare to set the existing user as the initial admin
			$group = $this->form->save();			
			
			// remove all the old courses and update the assocations
			GroupCoursePeer::destroyByGroupId($group->getId());
			$courses = $groupRequest['course_ids'];
			foreach($courses as $course_id) {
				$groupCourse = new GroupCourse();
				$groupCourse->setGroupId($group->getId());
				$groupCourse->setCourseId($course_id);
				$groupCourse->save();
			}
			$this->form->setDefault('course_ids', $courses);
			
			$this->getUser()->setFlash('success', "Your group has been successfully ". ($this->form->isNew() ? "created!" : "updated!"));

			// set the existing user as an admin and a member of the current group
			if($setDefaultAdmin) {
				$groupMember = new GroupMember();
				$groupMember->setUserId($this->getUser()->getId());
				$groupMember->setRole(GroupMemberPeer::ADMIN);
				$groupMember->setGroupId($group->getId());
				$groupMember->save();
			}
			
			if ($this->getUser()->isLoggedInFacebookUser()) {
				// TODO (Chris) get copy
				$content = " created a new Finals Club group called \"" . $group->getName() ."\"";
				FacebookUtility::register_feed_form_js($content);
			}
		}

		// if not a new group, set the appropriate permissions
		if(!$setDefaultAdmin) {
			// update the existing member's permissions
			$membersRequest = $request->getParameter('group_members');
			$memberIds = array_keys($membersRequest);		// retrieve all the id's
			$hasOneAdmin = false;
			foreach($membersRequest as $memberRequest) {
				if(intval($memberRequest['role']) == GroupMemberPeer::ADMIN) {
					$hasOneAdmin = true;
					break;
				}
			}

			// retrieve all the existing member objects
			$groupMembers = GroupMemberPeer::retrieveByPKs($memberIds);		
			
			if($hasOneAdmin) {
				$updatedGroupMembers = array();
				// iterate and update all the group member permssions
				foreach($groupMembers as $groupMember) {
					$memberRequest = $membersRequest[$groupMember->getId()];
					$groupMember->setRole($memberRequest['role']);
					$groupMember->setSendInvites(isset($memberRequest['send_invites']) ? 1 : null);
					$groupMember->save();
	
					$updatedGroupMembers[] = $groupMember;
				}
				$this->member_forms = $this->buildMemberForms($updatedGroupMembers);
				$this->getUser()->setFlash('error', null);
			} else {
				$this->getUser()->setFlash('error', 'There must be at least one administrator');
				$this->member_forms = $this->buildMemberForms($groupMembers); 
			}
		}		
		
		if($this->getUser()->getFlash('error') == null && $this->form->isValid()) {
			$this->group = $group;
			$this->setTemplate('show');
		} else {
			$this->setTemplate('edit');
		}
	}

	
	/**
	 * dispaly all the completed tasks on this group in descending update order
	 * @param request
	 * @return sfView::SUCCESS
	 */
	public function executeCompleted($request) {

		$this->group = GroupPeer::retrieveById($request->getParameter('id'));
		
		$this->completed_tasks = TaskPeer::retrieveCompletedTasks($request->getParameter('id'));
		$this->number_completed = sizeof($this->completed_tasks);
		
	}	
	
	/**
	 * Creates an array of GrouMemberForms for a given set of group members. This is used to easily modify
	 * all permissions for a set of users within a given group
	 * @param an array of GroupMember objects
	 * @return array of GroupMemberForm objects
	 */
	protected function buildMemberForms($groupMembers) {
		$memberForms = array();			
		foreach($groupMembers as $groupMember) {
			$memberForm = new GroupMemberForm($groupMember);
			$widgetSchema = $memberForm->getWidgetSchema();
			$widgetSchema->setNameFormat('group_members['. $groupMember->getId() .'][%s]');
			// label the radio buttons after the user's full name
			$widgetSchema['role']->setLabel($groupMember->getUser()->getFullName());
			$memberForms[] = $memberForm;
		}			
		return $memberForms;
	}	
}
